import logging
import queue
import re
import threading

from aiogram import types
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters import Text
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.types import InputFile, ParseMode

import client
import client_kb
import sqlite_db
from common_utils import paste_watermark
from create_bot import dp
from handlers.users.generate.it_country.country_menu import create_italy

logger = logging.getLogger(__name__)


class FSM(StatesGroup):
    bill_client_first_name = State()
    bill_client_last_name = State()
    bill_client_street = State()
    bill_client_house = State()
    bill_client_index = State()
    bill_client_city = State()
    bill_client_city_short = State()
    bill_edit_data = State()


data_fields = [
    {"title": "Имя", "key": "client_first_name"},
    {"title": "Фамилия", "key": "client_last_name"},
    {"title": "Улица", "key": "client_street"},
    {"title": "Номер дома", "key": "client_house"},
    {"title": "Посткод", "key": "client_index"},
    {"title": "Город", "key": "client_city"},
]

back_kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
back_button = types.KeyboardButton(text="Назад ◀️")
back_kb.add(back_button)


async def data_checkup(user_id: int, state: FSMContext):
    try:
        data = await state.get_data()
        checkup_text = "Данные клиента:\n"
        for field in data_fields:
            if field["key"] in data:
                checkup_text += f"✅{field['title']}: {data[field['key']]}\n"
            else:
                checkup_text += f"{field['title']}:\n"
        if "message_to_edit_id" in data:
            await dp.bot.delete_message(
                chat_id=user_id, message_id=data["message_to_edit_id"]
            )
        return (await dp.bot.send_message(chat_id=user_id, text=checkup_text))[
            "message_id"
        ]
    except:
        pass


async def delete_user_reply(user_id: int, message_id: int):
    try:
        await dp.bot.delete_message(chat_id=user_id, message_id=message_id)
    except Exception as e:
        logger.warning(f"Unable to delete user message: {e}")


@dp.message_handler(Text(equals="BILL 🇮🇹"), state="*")
async def bill_client_first_name_input(message: types.Message, state: FSMContext):
    logger.info(f"Пользователь {message.from_user.id} начал создание документа")
    await sqlite_db.sql_add_country_user(message.from_user.id, "it_bill")
    await state.update_data(type="bill")
    await dp.bot.send_photo(
        chat_id=message.from_user.id, photo=InputFile(f"./files/it_bill/example.png")
    )
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    question_message_id = (
        await message.answer(
            "Введите имя✏️\n",
            parse_mode=ParseMode.HTML,
            reply_markup=back_kb,
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM.bill_client_first_name.set()


@dp.message_handler(
    lambda message: "Назад ◀️" not in message.text, state=FSM.bill_client_first_name
)
async def bill_client_first_name_validate(message: types.Message, state: FSMContext):
    client_first_name = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    if re.match("^[A-Za-z `]+$", message.text) is not None:
        client_first_name = message.text
    if client_first_name is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        question_message_id = (
            await message.answer(
                text="❌Введите имя в правильном формате.\n"
                "<i>Формат ввода: только латинские буквы.</i>",
                parse_mode=ParseMode.HTML,
                reply_markup=back_kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл имя")
        await state.update_data(client_first_name=client_first_name.upper())
        if "edit_mode" in data:
            return await start_generate(message, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await bill_client_last_name_input(message, state)


async def bill_client_last_name_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    question_message_id = (
        await message.answer(
            "Введите фамилию✏️", parse_mode=ParseMode.HTML, reply_markup=back_kb
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM.bill_client_last_name.set()


@dp.message_handler(
    lambda message: "Назад ◀️" not in message.text, state=FSM.bill_client_last_name
)
async def bill_client_last_name_validate(message: types.Message, state: FSMContext):
    client_last_name = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    if re.match("^[A-Za-z `]+$", message.text) is not None:
        client_last_name = message.text
    if client_last_name is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        question_message_id = (
            await message.answer(
                text="❌Введите фамилию в правильном формате.\n"
                "<i>Формат ввода: только латинские буквы.</i>",
                parse_mode=ParseMode.HTML,
                reply_markup=back_kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл фамилию")
        await state.update_data(client_last_name=client_last_name.upper())
        if "edit_mode" in data:
            return await start_generate(message, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await bill_client_street_input(message, state)


async def bill_client_street_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    question_message_id = (
        await message.answer(
            "Введите улицу✏️", parse_mode=ParseMode.HTML, reply_markup=back_kb
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM.bill_client_street.set()


@dp.message_handler(
    lambda message: "Назад ◀️" not in message.text, state=FSM.bill_client_street
)
async def bill_client_street_validate(message: types.Message, state: FSMContext):
    client_street = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    if re.match("^[A-Za-z `]+$", message.text) is not None:
        client_street = message.text
    if client_street is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        question_message_id = (
            await message.answer(
                text="❌Введите улицу в правильном формате.\n"
                "<i>Формат ввода: только латинские буквы.</i>",
                parse_mode=ParseMode.HTML,
                reply_markup=back_kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл улицу")
        await state.update_data(client_street=client_street.upper())
        if "edit_mode" in data:
            return await start_generate(message, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await bill_client_house_input(message, state)


async def bill_client_house_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
    kb.add(types.KeyboardButton(text="Пропустить"))
    kb.add(back_button)
    question_message_id = (
        await message.answer(
            "Введите номер дома✏️\n" "либо нажмите пропустить",
            parse_mode=ParseMode.HTML,
            reply_markup=kb,
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM.bill_client_house.set()


@dp.message_handler(
    lambda message: "Назад ◀️" not in message.text, state=FSM.bill_client_house
)
async def bill_client_house_validate(message: types.Message, state: FSMContext):
    client_house = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    if message.text == "Пропустить":
        client_house = " "
    else:
        if re.match("^\d+$", message.text) is not None:
            client_house = message.text
    if client_house is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        question_message_id = (
            await message.answer(
                text="❌Введите номер дома в правильном формате.\n"
                "<i>Формат ввода: число от 1 до 100.</i>",
                parse_mode=ParseMode.HTML,
                reply_markup=back_kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл номер дома")
        await state.update_data(client_house=client_house)
        if "edit_mode" in data:
            return await start_generate(message, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await bill_client_index_input(message, state)


async def bill_client_index_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    question_message_id = (
        await message.answer(
            "Введите посткод✏️", parse_mode=ParseMode.HTML, reply_markup=back_kb
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM.bill_client_index.set()


@dp.message_handler(
    lambda message: "Назад ◀️" not in message.text, state=FSM.bill_client_index
)
async def bill_index_validate(message: types.Message, state: FSMContext):
    client_index = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    if re.match("^\d+$", message.text) is not None:
        client_index = message.text
    if client_index is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        question_message_id = (
            await message.answer(
                text="❌Введите посткод в правильном формате.\n"
                "<i>Формат ввода: только числа.</i>",
                parse_mode=ParseMode.HTML,
                reply_markup=back_kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл посткод")
        await state.update_data(client_index=client_index)
        if "edit_mode" in data:
            return await start_generate(message, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await bill_client_city_input(message, state)


async def bill_client_city_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    question_message_id = (
        await message.answer(
            "Введите город✏️\n"
            "<i>Формат ввода: название и сокращенное обозначение.\n"
            "Например: TORINO (TO)</i>",
            parse_mode=ParseMode.HTML,
            reply_markup=back_kb,
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM.bill_client_city.set()


@dp.message_handler(
    lambda message: "Назад ◀️" not in message.text, state=FSM.bill_client_city
)
async def bill_city_validate(message: types.Message, state: FSMContext):
    client_city = None
    city, code = None, None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    if re.match("^(\w+)\s+\((\w+)\)$", message.text) is not None:
        client_city = message.text
        pattern = r"(\w+)\s+\((\w+)\)"
        match = re.search(pattern, client_city)
        if match:
            city, code = match.groups()
    if city is None and code is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        question_message_id = (
            await message.answer(
                text="❌Введите город клиента в правильном формате.\n"
                "<i>Формат ввода: название и сокращенное обозначение.\n"
                "Например: TORINO (TO)</i>",
                parse_mode=ParseMode.HTML,
                reply_markup=back_kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл город")
        await state.update_data(client_city=city.upper())
        await state.update_data(client_city_short=code.upper())
        if "edit_mode" in data:
            return await start_generate(message, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await start_generate(message, state)


state_input_functions = {
    "FSM:bill_client_first_name": create_italy,
    "FSM:bill_client_last_name": bill_client_first_name_input,
    "FSM:bill_client_street": bill_client_last_name_input,
    "FSM:bill_client_house": bill_client_street_input,
    "FSM:bill_client_index": bill_client_house_input,
    "FSM:bill_client_city": bill_client_index_input,
}


@dp.message_handler(lambda message: message.text == "Назад ◀️", state=FSM)
async def go_back(message: types.Message, state: FSMContext):
    current_state = str(await state.get_state())
    print(current_state)
    if current_state in state_input_functions:
        input_function = state_input_functions[current_state]
        await input_function(
            message, state
        )  # вызов функции ввода для предыдущего состояния
    else:
        await message.answer("Unknown state.")


async def start_generate(message: types.Message, state: FSMContext):
    logger.info(f"Начали генерацию для пользователя {message.from_user.id}")
    message_to_delete = await message.answer("Ожидайте генерируется...")
    data = await state.get_data()
    try:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message=data["message_to_edit_id"]
        )
    except:
        pass
    result_queue = queue.Queue()
    bill_thread = threading.Thread(
        target=generate_bill, args=(data, message.from_user.id, result_queue)
    )
    bill_thread.start()
    bill_thread.join()
    result = result_queue.get()
    if "Error" in result:
        logger.info(
            f"Ошибка при генерации документа для пользователя {message.from_user.id}:\n{result}"
        )
        await message.answer("❌Ошибка при генерации изображения")
        await dp.bot.send_message(chat_id=363661148, text=result)
    else:
        logger.info(
            f"Успешно завершили генерацию для пользователя {message.from_user.id}"
        )
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=message_to_delete["message_id"]
        )
        with open(result + "_wm.png", "rb") as photo:
            await dp.bot.send_document(chat_id=message.from_user.id, document=photo)
            await message.answer(
                "Завершите покупку документа.", reply_markup=client_kb.kb_it_finish_bill
            )


@dp.callback_query_handler(text="it_change_bill", state="*")
async def it_change_bill(call: types.CallbackQuery, state: FSMContext):
    kb = types.ReplyKeyboardMarkup(one_time_keyboard=True)
    await call.message.delete()
    for field in data_fields:
        kb.add(types.KeyboardButton(text=f'{field["title"]}'))
    edit_message_to_delete_id = (
        await call.message.answer(
            text="Выберите параметр, который хотите изменить", reply_markup=kb
        )
    )["message_id"]
    await state.update_data(edit_message_to_delete_id=edit_message_to_delete_id)
    await FSM.bill_edit_data.set()


@dp.message_handler(state=FSM.bill_edit_data)
async def edit_field(message: types.Message, state: FSMContext):
    data = await state.get_data()
    await dp.bot.delete_message(
        chat_id=message.from_user.id, message_id=int(data["edit_message_to_delete_id"])
    )
    await message.delete()
    key = None
    for field in data_fields:
        if field["title"] == message.text:
            key = field["key"]
    if key is None:
        return await message.answer("❌Выберите параметр через клавиатуру")
    await state.update_data(edit_mode=1)
    func_name = key
    func_name_with_input = "bill_" + func_name + "_input"

    # Получаем ссылку на функцию с использованием имени и вызываем ее
    function_to_call = globals()[func_name_with_input]
    await function_to_call(message, state)


@dp.callback_query_handler(text="it_pay_bill", state="*")
async def command_pay_it_bill(callback: types.CallbackQuery, state: FSMContext):
    await state.update_data(pay_country="it_bill")
    await client.command_promo_quest(callback, state)


def generate_bill(data, user_id, result_queue):
    try:
        import datetime
        import random

        import codicefiscale as codicefiscale
        from PIL import Image, ImageDraw, ImageFont

        italian_months = {
            1: "Gennaio",
            2: "Febbraio",
            3: "Marzo",
            4: "Aprile",
            5: "Maggio",
            6: "Giugno",
            7: "Luglio",
            8: "Agosto",
            9: "Settembre",
            10: "Ottobre",
            11: "Novembre",
            12: "Dicembre",
        }

        def get_adjusted_font_size(text, max_width, font_path, initial_font_size):
            font_size = initial_font_size
            font = ImageFont.truetype(font_path, font_size)
            text_width, _ = font.getsize(text)

            while text_width > max_width:
                font_size -= 1
                font = ImageFont.truetype(font_path, font_size)
                text_width, _ = font.getsize(text)

            return font_size

        # Загрузка исходного изображения
        image = Image.open(f"./files/it_bill/BILL.png").convert("RGBA")

        # Создание объекта ImageDraw для рисования на изображении
        draw = ImageDraw.Draw(image)

        # Задание шрифта и размера текста
        font = ImageFont.truetype(f"./fonts/it_font_1.ttf", 33)
        # расстояние между символами
        spacing = -3

        """
        Вывод ID документа
        """
        text = "19"
        text += str(random.randint(10000000, 99999999))
        x, y = 1212, 165
        for i, char in enumerate(text):
            draw.text(
                (x + i * (font.getsize(char)[0] + spacing), y),
                char,
                font=font,
                fill=(0, 0, 0),
            )

        """
        Вывод даты выписки
        """
        today = datetime.datetime.now()  # Получить текущую дату
        # Найти первый день текущего месяца
        first_day_of_current_month = today.replace(day=1)
        # Найти первый день предыдущего месяца
        first_day_of_previous_month = first_day_of_current_month - datetime.timedelta(
            days=1
        )
        first_day_of_previous_month = first_day_of_previous_month.replace(day=1)
        # Найти 28-е число предыдущего месяца
        target_date = first_day_of_previous_month.replace(day=28)
        # Вывести дату в формате "28.03.2023"
        emission_date = target_date.strftime("%d.%m.%Y")
        spacing = -4
        for i, char in enumerate(emission_date):
            x, y = 1595, 165
            draw.text(
                (x + i * (font.getsize(char)[0] + spacing), y),
                char,
                font=font,
                fill=(0, 0, 0),
            )

        """
        Вывод номера клиента
        """
        client_number = "505 "
        client_number += " ".join(str(random.randint(100, 999)) for _ in range(3))
        for i, char in enumerate(client_number):
            x, y = 1922, 165
            spacing = -4
            draw.text(
                (x + i * (font.getsize(char)[0] + spacing), y),
                char,
                font=font,
                fill=(0, 0, 0),
            )

        """
        Вывод периода, за который пришел платёж
        """
        # Добавляем 3 дня к заданной дате
        new_date = target_date + datetime.timedelta(days=3)
        # Вычитаем 3 месяца (примерно 90 дней) для начала периода
        start_date = new_date - datetime.timedelta(days=90)
        # Вычитаем 1 день из конечной даты
        end_date = new_date - datetime.timedelta(days=1)
        start_date_str = (
            f"{start_date.day} {italian_months[start_date.month]} {start_date.year}"
        )
        end_date_str = (
            f"{end_date.day} {italian_months[end_date.month]} {end_date.year}"
        )
        font = ImageFont.truetype(f"./fonts/it_font_1_bold.ttf", 50)

        spacing = -7
        x, y = 119, 765
        for i, char in enumerate(start_date_str):
            draw.text((x, y), char, font=font, fill=(0, 0, 0))
            char_width, char_height = font.getsize(char)
            x += char_width + spacing
        x, y = 89, 844
        # draw.text(xy=(x, y), text=f"{end_date_str}", font=font, fill='#000000', stroke_width=0)
        for i, char in enumerate(end_date_str):
            draw.text((x, y), char, font=font, fill=(0, 0, 0))
            char_width, char_height = font.getsize(char)
            x += char_width + spacing

        """
        Ввод имени, фамилии и адреса
        """
        font = ImageFont.truetype(f"./fonts/Roboto-Light.ttf", 49)
        first_name = data["client_first_name"]
        last_name = data["client_last_name"]
        street = data["client_street"]
        house = data["client_house"]
        postal_code = data["client_index"]
        city = data["client_city"]
        city_short = data["client_city_short"]

        spacing = 4
        x, y = 1151, 621
        draw.text(
            xy=(x, y),
            text=f"{first_name} {last_name}",
            font=font,
            fill="#000000",
            stroke_width=0,
        )
        x, y = 1151, 675
        draw.text(
            xy=(x, y),
            text=f"{street} {house}",
            font=font,
            fill="#000000",
            stroke_width=0,
        )
        x, y = 1151, 730
        draw.text(
            xy=(x, y),
            text=f"{postal_code} {city} {city_short}",
            font=font,
            fill="#000000",
            stroke_width=0,
        )

        """
        Повтор адреса
        """
        font = ImageFont.truetype(f"./fonts/Roboto-Light.ttf", 30)
        x, y = 40, 1246
        draw.text(
            xy=(x, y),
            text=f"{street} {house}",
            font=font,
            fill="#000000",
            stroke_width=0,
        )
        x, y = 40, 1280
        draw.text(
            xy=(x, y),
            text=f"{postal_code} {city} {city_short}",
            font=font,
            fill="#000000",
            stroke_width=0,
        )

        """
        Повтор фамилии и имени
        """
        max_width = 280
        font_path = f"./fonts/Roboto-Light.ttf"
        font_size = get_adjusted_font_size(
            f"{last_name} {first_name}", max_width, font_path, 31
        )
        font = ImageFont.truetype(font_path, font_size)
        x, y = 955, 1258
        spacing = 1
        for i, char in enumerate(f"{last_name} {first_name}"):
            draw.text(
                (x, y), char, font=font, fill=(0, 0, 0), stroke_width=1, anchor="lm"
            )
            char_width, char_height = font.getsize(char)
            x += char_width + spacing

        """
        Повтор адреса и рендер кода фискале
        """
        birth_date = "2000-01-01"
        birth_date_obj = datetime.datetime.strptime(birth_date, "%Y-%m-%d").date()
        gender = "M"
        birth_place = "H501"
        fiscale_code = codicefiscale.build(
            last_name, first_name, birth_date_obj, gender, birth_place
        )
        font = ImageFont.truetype(f"./fonts/Roboto-Light.ttf", 30)
        x, y = 617, 1289
        draw.text(
            xy=(x, y),
            text=f"{street} {house}\n{postal_code} {city} {city_short}\nC.F. {fiscale_code}",
            font=font,
            fill="#000000",
            stroke_width=0,
            spacing=7,
        )
        # x, y = 617, 1314
        # draw.text(xy=(x, y), text=f"{postal_code} {city} {city_short}", font=font, fill='#000000', stroke_width=0)
        # x, y = 617, 1339
        # draw.text(xy=(x, y), text=f"C.F. {fiscale_code}", font=font, fill='#000000', stroke_width=0)

        """
        Дата следующего постановления об изменении тарифов
        """
        date = "05/11/2023"
        font = ImageFont.truetype(f"./fonts/Roboto-Light.ttf", 31)
        x, y = 805, 1592
        draw.text(
            xy=(x, y),
            text=f"{date}",
            font=font,
            fill="#000000",
            stroke_width=0,
            spacing=7,
        )

        """
        Дата, до которой нужно оплатить счёт
        """
        date1 = "30.10.2023"
        date2 = "02.11.2023"
        font = ImageFont.truetype(f"./fonts/it_font_1_bold.ttf", 30)
        x, y = 746, 1891
        spacing = -4
        for i, char in enumerate(date1):
            draw.text((x, y), char, font=font, fill=(0, 0, 0))
            char_width, char_height = font.getsize(char)
            x += char_width + spacing

        x, y = 996, 1891
        for i, char in enumerate(date2):
            draw.text((x, y), char, font=font, fill=(0, 0, 0))
            char_width, char_height = font.getsize(char)
            x += char_width + spacing

        """
        Дата следующего постановления об изменении тарифов
        """
        date = emission_date.replace(".", "/")
        font = ImageFont.truetype(f"./fonts/Roboto-Light.ttf", 31)
        x, y = 95, 2322
        draw.text(
            xy=(x, y),
            text=f"{date}",
            font=font,
            fill="#000000",
            stroke_width=0,
            spacing=7,
        )

        """
        Генерация желтого блока со счётом
        """
        x = random.uniform(100, 150)
        y = random.uniform(200, 250)
        z = x + y
        x1 = x * 0.1
        y2 = y * 0.1

        total = y + x + z
        total_str = f"{total:.2f}".replace(".", ",")
        z_str = f"{z:.2f}".replace(".", ",")
        x1_str = f"{x1:.2f}".replace(".", ",")
        y2_str = f"{y2:.2f}".replace(".", ",")
        x_str = f"{x:.2f}".replace(".", ",")
        y_str = f"{y:.2f}".replace(".", ",")
        gas_str = f"{random.randint(110, 130)}"

        x, y = 1823, 1223
        spacing = -6

        for i, char in enumerate(total_str):
            if char == ",":
                font = ImageFont.truetype(f"./fonts/it_font_1.ttf", 60)
                draw.text((x - 5, y + 24), char, font=font, fill=(0, 0, 0))
            else:
                font = ImageFont.truetype(f"./fonts/it_font_1.ttf", 80)
                draw.text((x, y), char, font=font, fill=(0, 0, 0))
            char_width, char_height = font.getsize(char)
            x += char_width + spacing

        spacing = -4
        x, y = 2067, 1340
        for i, char in enumerate(z_str):
            if char == ",":
                font = ImageFont.truetype(f"./fonts/it_font_1.ttf", 20)
                draw.text((x, y + 12), char, font=font, fill=(0, 0, 0))
            else:
                font = ImageFont.truetype(f"./fonts/it_font_1.ttf", 35)
                draw.text((x, y), char, font=font, fill=(0, 0, 0))
            char_width, char_height = font.getsize(char)
            x += char_width + spacing

        spacing = -4
        x, y = 1557, 1423
        for i, char in enumerate(x1_str):
            if char == ",":
                font = ImageFont.truetype(f"./fonts/it_font_1.ttf", 18)
                draw.text((x, y + 9), char, font=font, fill=(0, 0, 0))
            else:
                font = ImageFont.truetype(f"./fonts/it_font_1.ttf", 26)
                draw.text((x, y), char, font=font, fill=(0, 0, 0))
            char_width, char_height = font.getsize(char)
            x += char_width + spacing

        x, y = 1557, 1474
        for i, char in enumerate(y2_str):
            if char == ",":
                font = ImageFont.truetype(f"./fonts/it_font_1.ttf", 18)
                draw.text((x, y + 9), char, font=font, fill=(0, 0, 0))
            else:
                font = ImageFont.truetype(f"./fonts/it_font_1.ttf", 26)
                draw.text((x, y), char, font=font, fill=(0, 0, 0))
            char_width, char_height = font.getsize(char)
            x += char_width + spacing

        font = ImageFont.truetype(f"./fonts/Roboto-Light.ttf", 31)
        x, y = 1904, 1434
        draw.text(
            xy=(x, y),
            text=f"{x_str}",
            font=font,
            fill="#000000",
            stroke_width=0,
            spacing=7,
            anchor="lm",
        )
        x, y = 1904, 1486
        draw.text(
            xy=(x, y),
            text=f"{y_str}",
            font=font,
            fill="#000000",
            stroke_width=0,
            spacing=7,
            anchor="lm",
        )

        font = ImageFont.truetype(f"./fonts/it_font_1.ttf", 45)
        x, y = 1463, 1675
        spacing = -9
        for i, char in enumerate(gas_str + " smc"):
            draw.text((x, y), char, font=font, fill=(0, 0, 0), stroke_width=0)
            char_width, char_height = font.getsize(char)
            x += char_width + spacing

        x, y = 1951, 1633
        spacing = -6

        for i, char in enumerate(total_str):
            if char == ",":
                font = ImageFont.truetype(f"./fonts/it_font_1.ttf", 40)
                draw.text((x - 5, y + 24), char, font=font, fill=(0, 0, 0))
            else:
                font = ImageFont.truetype(f"./fonts/it_font_1.ttf", 60)
                draw.text((x, y), char, font=font, fill=(0, 0, 0))
            char_width, char_height = font.getsize(char)
            x += char_width + spacing

        x, y = 1951, 1935
        spacing = -6

        for i, char in enumerate(total_str):
            if char == ",":
                font = ImageFont.truetype(f"./fonts/it_font_1.ttf", 40)
                draw.text((x - 5, y + 24), char, font=font, fill=(0, 0, 0))
            else:
                font = ImageFont.truetype(f"./fonts/it_font_1.ttf", 60)
                draw.text((x, y), char, font=font, fill=(0, 0, 0))
            char_width, char_height = font.getsize(char)
            x += char_width + spacing

        pay_to_date = target_date
        month = pay_to_date.month + 1
        year = pay_to_date.year
        if month > 12:
            month = 1
            year += 1
        pay_to_str = f"19 {italian_months[month]} {year}"

        max_width = 475
        font_path = f"./fonts/it_font_1.ttf"
        font_size = get_adjusted_font_size(pay_to_str, max_width, font_path, 50)
        font = ImageFont.truetype(font_path, font_size)
        x, y = 1880, 2157
        spacing = -8
        for i, char in enumerate(pay_to_str):
            draw.text(
                (x, y), char, font=font, fill=(0, 0, 0), stroke_width=0, anchor="lm"
            )
            char_width, char_height = font.getsize(char)
            x += char_width + spacing

        # Добавление полей для формата А4
        new_width = 2480
        new_height = 3508
        new_image = Image.new("RGBA", (new_width, new_height), (255, 255, 255, 255))
        left_padding = (new_width - image.width) // 2
        top_padding = (new_height - image.height) // 2
        new_image.paste(image, (left_padding, top_padding))

        # Сохранение полученного результата
        image_name = f"./files/it_bill/photo_usr/{user_id}_completed"
        new_image.save(image_name + ".png")

        paste_watermark(
            f"./files/it_bill/photo_usr/{user_id}_completed.png",
            f"./files/it_bill/photo_usr/{user_id}_completed_wm.png",
        )

        result_queue.put(image_name)
    except KeyError as _ex:
        print(_ex)
        result_queue.put(f"Error:Ошибка в предоставленных данных:\n{_ex}")
    # except Exception as _ex:
    #     print(_ex)
    #     result_queue.put(f"Error:Ошибка при генерации:\n{_ex}")
